package com.qupai.lib_base.utils

import android.app.ActivityManager
import android.content.Context
import android.os.Debug
import android.os.Environment
import android.os.StatFs
import android.os.SystemClock.sleep
import android.text.TextUtils
import android.util.Log
import com.blankj.utilcode.util.LogUtils
import com.qupai.lib_base.app.BaseApplication
import com.qupai.lib_base.utils.UsbUtils
import java.io.*

object AppUtil {

    fun getStorageInfo(): String {
        // 获取内部存储路径
        val path: File = Environment.getDataDirectory()
        val stat = StatFs(path.path)

        // 获取块大小
        val blockSize: Long = stat.blockSizeLong
        // 总块数
        val totalBlocks: Long = stat.blockCountLong
        // 可用块数
        val availableBlocks: Long = stat.availableBlocksLong

        // 计算总大小、可用大小和已用大小（单位：字节）
        val totalSize = blockSize * totalBlocks
        val availableSize = blockSize * availableBlocks
        val usedSize = totalSize - availableSize

        // 计算百分比
        val usedPercent = (usedSize.toDouble() / totalSize.toDouble()) * 100

        // 将结果格式化为 MB / GB 等
//        磁盘信息
//        总大小: 10,85 GB
//        已使用: 4,93 GB
//        可用: 5,92 GB
//        使用率: 45,43%
        return """
        磁盘信息
        总大小: ${formatSize(totalSize)}
        已使用: ${formatSize(usedSize)}
        可用: ${formatSize(availableSize)}
        使用率: ${String.format("%.2f", usedPercent)}%
    """.trimIndent()
    }

    fun formatSize(size: Long): String {
        val kb = 1024
        val mb = kb * 1024
        val gb = mb * 1024

        return when {
            size >= gb -> String.format("%.2f GB", size.toFloat() / gb)
            size >= mb -> String.format("%.2f MB", size.toFloat() / mb)
            size >= kb -> String.format("%.2f KB", size.toFloat() / kb)
            else -> "$size B"
        }
    }


    fun logMemory() {
        val activityManager =
            BaseApplication.psaApp.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val memInfo = ActivityManager.MemoryInfo() //存放内存信息的对象
        activityManager.getMemoryInfo(memInfo)
        val totalMem = memInfo.totalMem / 1000000 //总内存
        val availMem = memInfo.availMem / 1000000 //可用内存
        val isLowMem = memInfo.lowMemory //是否达到最低内存
        val threshold = memInfo.threshold / 1000000 //临界值，达到这个值，进程就要被杀死
        //最大分配内存
        val memory = activityManager.memoryClass
        //最大分配内存获取方法2
        val maxMemory = (Runtime.getRuntime().maxMemory() * 1.0 / (1024 * 1024)).toFloat()
        //当前分配的总内存
        val totalMemory = (Runtime.getRuntime().totalMemory() * 1.0 / (1024 * 1024)).toFloat()
        //剩余内存
        val freeMemory = (Runtime.getRuntime().freeMemory() * 1.0 / (1024 * 1024)).toFloat()
        val memoryInfo = Debug.MemoryInfo()
        Debug.getMemoryInfo(memoryInfo)
        val javaHeap = memoryInfo.getMemoryStat("summary.java-heap")
        val nativeHeap = memoryInfo.getMemoryStat("summary.native-heap")
        val code = memoryInfo.getMemoryStat("summary.code")
        val stack = memoryInfo.getMemoryStat("summary.stack")
        val graphics = memoryInfo.getMemoryStat("summary.graphics")
        val privateOther = memoryInfo.getMemoryStat("summary.private-other")
        val system = memoryInfo.getMemoryStat("summary.system")
        val swap = memoryInfo.getMemoryStat("summary.total-swap")
        LogUtils.d(
            getTotalRom()+
            " 系统总内存: " + totalMem + "M"+
            " 系统可用内存: " + availMem + "M"+
            " 是否达到最低内存: $isLowMem"+
            " 内存临界值: " + threshold + "M +低于此值后台开始杀进程"+
            " memory: " + memory + "M"+
            " maxMemory: " + maxMemory + "M"+
            " totalMemory 已分配: " + totalMemory + "M"+
            " freeMemory 已分配剩余: " + freeMemory + "M"+
            " javaHeap: " + formatSize(javaHeap)+
            " nativeHeap: " + formatSize(nativeHeap)+
            " code: " + formatSize(code)+
            " stack: " + formatSize(stack)+
            " graphics: " + formatSize(graphics)+
            " privateOther: " + formatSize(privateOther)+
            " system: " + formatSize(system)+
            " swap: " + formatSize(swap)
        )

        LogUtils.d(getStorageInfo())
//        LogUtils.e(
//            getTotalRom(),
//            "系统总内存: " + totalMem + "M",
//            "系统可用内存: " + availMem + "M",
//            "是否达到最低内存: $isLowMem",
//            "内存临界值: " + threshold + "M ,低于此值后台开始杀进程",
//            "memory: " + memory + "M",
//            "maxMemory: " + maxMemory + "M",
//            "totalMemory 已分配: " + totalMemory + "M",
//            "freeMemory 已分配剩余: " + freeMemory + "M",
//            "javaHeap: " + formatSize(javaHeap),
//            "nativeHeap: " + formatSize(nativeHeap),
//            "code: " + formatSize(code),
//            "stack: " + formatSize(stack),
//            "graphics: " + formatSize(graphics),
//            "privateOther: " + formatSize(privateOther),
//            "system: " + formatSize(system),
//            "swap: " + formatSize(swap)
//        )
    }

    private fun formatSize(value: String): String? {
        return if (TextUtils.isEmpty(value)) "0M" else (value.toLong() / 1024).toString() + "M"
    }

    /**
     * ROM内存大小，返回 64G/128G/256G/512G
     * @return
     */
    private fun getTotalRom(): String? {
        val dataDir = Environment.getDataDirectory()
        val stat = StatFs(dataDir.path)
        val blockSize = stat.blockSizeLong
        val totalBlocks = stat.blockCountLong
        val availableCounts = stat.availableBlocksLong //获取可用的block数
        val availROMSize = availableCounts * blockSize //可用内部存储大小
        val size = totalBlocks * blockSize
        val GB = (1024 * 1024 * 1024).toLong()
        val deviceRomMemoryMap = longArrayOf(
            2 * GB,
            4 * GB,
            8 * GB,
            16 * GB,
            32 * GB,
            64 * GB,
            128 * GB,
            256 * GB,
            512 * GB,
            1024 * GB,
            2048 * GB
        )
        val displayRomSize = arrayOf(
            "2GB",
            "4GB",
            "8GB",
            "16GB",
            "32GB",
            "64GB",
            "128GB",
            "256GB",
            "512GB",
            "1024GB",
            "2048GB"
        )
        var i: Int
        i = 0
        while (i < deviceRomMemoryMap.size) {
            if (size <= deviceRomMemoryMap[i]) {
                break
            }
            if (i == deviceRomMemoryMap.size) {
                i--
            }
            i++
        }
        return "系统Rom内存: " + displayRomSize[i] + " 可用ROM内存：" + availROMSize/1024/1024 + "MB"
    }

    fun resetUsbOtg() {
        saveDataToFile("150 0"); //usb otg关
        saveDataToFile("153 0"); //usb otg关
        sleep(1000)
        saveDataToFile("150 1"); //usb otg开
        saveDataToFile("153 1"); //usb otg开
        LogUtils.e("重启USB")
    }

    private fun saveDataToFile(data: String) {
        var writer: BufferedWriter? = null
        val file = File("/proc/proembed/gpio")
        if (!file.exists()) {
            try {
                file.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        try {
            writer = BufferedWriter(OutputStreamWriter(FileOutputStream(file, false), "UTF-8"))
            writer.write(data)
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                writer?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
}